package com.tinyideatech.admin.controller.car;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.request.WxPayOrderQueryRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.google.zxing.WriterException;
import com.tinyideatech.common.core.controller.BaseController;
import com.tinyideatech.common.core.entity.ApiResult;
import com.tinyideatech.common.core.entity.PageResult;
import com.tinyideatech.common.core.text.Convert;
import com.tinyideatech.common.json.JSONObject;
import com.tinyideatech.common.utils.StringUtils;
import com.tinyideatech.framework.dto.FTP;
import com.tinyideatech.framework.service.VerifyWxService;
import com.tinyideatech.framework.utils.ExcelUtils;
import com.tinyideatech.framework.utils.FtpUtil;
import com.tinyideatech.framework.utils.IpUtils;
import com.tinyideatech.system.entity.CarOrder;
import com.tinyideatech.system.service.ICarGoodsService;
import com.tinyideatech.system.service.ICarOrderService;
import com.tinyideatech.wechat.utils.CommonUtil;
import com.tinyideatech.wechat.utils.RandomUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Arrays;

import static com.tinyideatech.common.core.entity.ApiResult.warn;

/**
 * @author zhangy-5
 * @date 2019-09-09
 */

@Api("微信支付")
@Controller
@RequestMapping("/ws/v2/pay")
public class CarOrderController extends BaseController {

    private static final Logger log = LoggerFactory.getLogger(CarOrderController.class);

    private WxPayService wxService;

    @Autowired
    private ICarOrderService carOrderService;

    @Autowired
    private VerifyWxService verifyWxService;

    @Autowired
    private ICarGoodsService goodsService;

    @Value("${wx.pay.notifyUrl.adas}")
    private String notifyUrl;

    @Value("${wx.pay.tradeType}")
    private String tradeType;

    @Autowired
    private FTP ftpCatalog;

    @Autowired
    public CarOrderController(WxPayService wxService) {
        this.wxService = wxService;
    }

    @GetMapping()
    public String list() {
        return "system/order/list";
    }

    @GetMapping("/add")
    public String add() {
        return "system/order/add";
    }

    @GetMapping("/edit/{id}")
    public String carOrderEdit(
            @PathVariable("id") Long id,
            ModelMap map
    ) {
        CarOrder carOrder = carOrderService.getById(id);
        map.addAttribute("carOrder", carOrder);
        return "system/order/edit";
    }


    @PostMapping("/list")
    public PageResult list(CarOrder carOrder) {
        QueryWrapper<CarOrder> qw = new QueryWrapper<>();
        if (StringUtils.isNotEmpty("")) {
            qw.like("", "");
        }
        IPage<CarOrder> page = startPage();
        IPage<CarOrder> carOrderList = carOrderService.page(page, qw);
        return page(carOrderList);
    }


    @PostMapping("/save")
    public ApiResult save(
            CarOrder sysRole
    ) {
        carOrderService.saveOrUpdate(sysRole);
        return success();
    }


    @PostMapping("/remove")
    public ApiResult remove(
            String ids
    ) {
        Long[] carOrderIds = Convert.toLongArray(ids);
        carOrderService.removeByIds(Arrays.asList(carOrderIds));
        return success();
    }

    @PostMapping("/changeStatus")
    public ApiResult changeStatus(CarOrder carOrder) {
        carOrderService.changeStatus(carOrder);
        return success();
    }


    /**
     * adas下单接口
     * <p>
     * response.setContentType("image/jpeg");
     * response.setHeader("Pragma", "no-cache");
     * response.setHeader("Cache-Control", "no-cache");
     * response.setIntHeader("Expires", -1);
     * ImageIO.write(image, "JPEG", response.getOutputStream());
     *
     * @param deviceId
     * @param feature
     * @param request
     * @return
     */
    @ApiOperation(value = "调试用发起订单")
    @PostMapping("/scanpay")
    @ResponseBody
    private ApiResult rewardWxpay(@RequestParam String deviceId,
                                  @RequestParam Integer feature,
                                  @RequestParam String code,
                                  HttpServletRequest request) {
        try {
            JSONObject resultJSON = new JSONObject();
            JSONObject compare = carOrderService.compareQRcodeTime(deviceId, feature);
            if (compare.size() != 0) {
                return success(compare);
            }
            if (carOrderService.verifyStatus(deviceId, code, feature)) {
                return warn("car already active");
            }
            WxPayUnifiedOrderRequest wxReq = new WxPayUnifiedOrderRequest();
            String productId = RandomUtil.generateStr(10, deviceId, feature);
            String outTradeNo = RandomUtil.getOrderIdByUUId();
            String expireTime = CommonUtil.getOrderExpireTime(15 * 60 * 1000L);
            String ip = IpUtils.getRealIP(request);
            wxReq.setBody(verifyWxService.generateDetail(feature));
            wxReq.setDetail("鑫洋泉商品-激活码激活");
            wxReq.setOutTradeNo(outTradeNo);
            wxReq.setTotalFee(goodsService.getPrice(feature));
            wxReq.setSpbillCreateIp(ip);
            wxReq.setTimeExpire(expireTime);
            wxReq.setProductId(productId);
            wxReq.setNotifyUrl(notifyUrl);
            wxReq.setTradeType(tradeType);
            WxPayUnifiedOrderResult result = this.wxService.unifiedOrder(wxReq);
            log.info(String.format("result:[%s]", result.toString()));
            boolean isSuccess = verifyWxService.verifyWxPayUnifiedOrderResult(result, deviceId, outTradeNo, feature, productId, code, expireTime);
            if (isSuccess) {
                log.info(String.format("CodeURL:[%s]", result.getCodeURL()));
                BufferedImage image = CommonUtil.getQRCodeImge(result.getCodeURL());
                String fileName = "wx" + outTradeNo + ".png";
                FtpUtil.uploadFileToFtp(ftpCatalog.getFTPPathImgFtp(), fileName, FtpUtil.bufferedImageToInputStream(image));
                resultJSON.put("url", ftpCatalog.getFullPathImgFtp() + fileName);
                resultJSON.put("prepayId", result.getPrepayId());
                return ApiResult.success(resultJSON);
            }
        } catch (WxPayException e) {
            e.printStackTrace();
            log.error("unknow error:" + e.getMessage());
        } catch (WriterException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return error();
    }


    /**
     * 查询订单
     *
     * @param wxPayOrderQueryRequest
     * @return
     * @throws WxPayException
     */
    @ApiOperation(value = "查询订单")
    @PostMapping("/queryOrder")
    @ResponseBody
    public WxPayOrderQueryResult queryOrder(@RequestBody WxPayOrderQueryRequest wxPayOrderQueryRequest) throws WxPayException {
        return this.wxService.queryOrder(wxPayOrderQueryRequest);
    }

    /**
     * 查询订单
     *
     * @param prepayId
     * @return
     * @throws WxPayException
     */
    @ApiOperation(value = "校验订单")
    @PostMapping("/verify/order")
    @ResponseBody
    public ApiResult verifyOrder(@RequestParam String prepayId) {
        boolean condition = carOrderService.verifyOrder(prepayId);
        if (condition) {
            return ApiResult.success("", "");
        }
        return warn("", "");
    }

    /**
     * 扫码支付回调
     *
     * @param xmlData
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "扫码支付回调通知处理")
    @PostMapping("/notify/scanpay")
    @ResponseBody
    public String parseScanPayNotifyResult(@RequestBody String xmlData) throws Exception {
        final WxPayOrderNotifyResult result = this.wxService.parseOrderNotifyResult(xmlData);
        if (verifyWxService.verifyNotifyResult(result, xmlData)) {
            return WxPayNotifyResponse.success("SUCCESS");
        } else {
            return WxPayNotifyResponse.fail("FAIL");
        }
    }

}
